#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include "buffer.h"


int init_buffer(buffer *buff, int size) {
	buff->size = size;
	buff->in = 0;
	buff->out = 0;
	pthread_mutex_init(&(buff->lock), NULL);
	sem_init(&(buff->empty), 0, buff->size-1);
	sem_init(&(buff->full), 0, 0);
	buff->items = (buffer_item*) malloc(size*sizeof(buffer_item));
	if(buff->items != NULL) {
		return size;
	}
	else {
		return -1;
	}
}

int buffer_insert(buffer *buff, buffer_item item) {
	sem_wait(&(buff->empty));
	pthread_mutex_lock(&(buff->lock));

	if(((buff->in + 1) % buff->size) == buff->out) {
		return -1;
	}
	buff->items[buff->in] = item;
	buff->in = (buff->in+1) % buff->size;

	pthread_mutex_unlock(&(buff->lock));
	sem_post(&(buff->full));
	return 0;
}

int buffer_remove(buffer *buff, buffer_item *item) {
	sem_wait(&(buff->full));
	pthread_mutex_lock(&(buff->lock));

	if(buff->in == buff->out) {
		return -1;
	}
	*item = buff->items[buff->out];
	buff->out = (buff->out+1) % buff->size;

	pthread_mutex_unlock(&(buff->lock));
	sem_post(&(buff->empty));
	return 0;
}

int destroy_buffer(buffer *buff) {
	pthread_mutex_lock(&(buff->lock));
	if(buff->items != NULL) {
		buff->size = 1;
		free(buff->items);
	}
	//pthread_mutex_unlock(&(buff->lock));
	return 0;
}
